package com.example.webdemo.webdemo1;

import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.target.SingletonTargetSource;

import java.util.concurrent.*;

public class CustomScheduledThreadPoolExecutor<V> extends ScheduledThreadPoolExecutor {

    public CustomScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory) {
        super(corePoolSize, threadFactory);
    }


    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        CustomScheduledFuture future;
        CustomDecoratedRunnable runnable = null;
        if (r instanceof CustomScheduledFuture) {
            future = (CustomScheduledFuture) r;
            runnable = (CustomDecoratedRunnable) future.getRunnable();
        }
        CustomScheduledFuture customScheduledFuture = runnable.getCustomScheduledFuture();

        CustomFutureCallBack customFutureCallBack = customScheduledFuture.getCustomFutureCallBack();
        if (customFutureCallBack != null) {
            if (t != null) {
                customFutureCallBack.onException(t);
            } else {
                customFutureCallBack.onSuccess(customScheduledFuture);
            }
        }

    }


    @Override
    public CustomScheduledFuture<V> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
        /**
         * 将future设置到task中
         */
        CustomScheduledFuture customScheduledFuture = new CustomScheduledFuture();

        CustomDecoratedRunnable customDecoratedRunnable = new CustomDecoratedRunnable(command,customScheduledFuture);
        ScheduledFuture<?> scheduledFuture = super.scheduleAtFixedRate(customDecoratedRunnable,
                initialDelay, period, unit);

        /**
         * 将返回的future，设置到我们包装过的future
         */
        customScheduledFuture.setScheduledFuture((RunnableScheduledFuture) scheduledFuture);

        return customScheduledFuture;
    }

    @Override
    protected <V> RunnableScheduledFuture<V> decorateTask(Runnable runnable, RunnableScheduledFuture<V> task) {
        CustomScheduledFuture<V> future = new CustomScheduledFuture<>();
        future.setRunnable(runnable);
        future.setScheduledFuture(task);
        return future;
    }

}
